﻿bob.ns.setNs('bob.collections.tests', {

    TestCollections: function () {

        this.test_Enumerator = function () {

            bob.assert.throwsError(function () { new bob.collections.Enumerator(null, function () { }); });
            bob.assert.throwsError(function () { new bob.collections.Enumerator(function () { }, null); });

            var array = [1, 2, 3];
            var index = 0;
            var fnHasNext = function () { return index <= (array.length - 1); };
            var fnGetNext = function () { return array[index++]; };
            var fnGetIndex = function () { return index; };
            var arrayEnum = new bob.collections.Enumerator(fnHasNext, fnGetNext, fnGetIndex);

            bob.assert.isUndefined(arrayEnum.get_current());
            for (var i = 0; i < array.length; i++) {
                bob.assert.isTrue(arrayEnum.next());
                bob.assert.equals(i + 1, index);
                bob.assert.equals(array[i], arrayEnum.get_current());
            }
            bob.assert.isFalse(arrayEnum.next());

        };

        this.test_arrayEnumerator = function () {

            bob.assert.throwsError(function () { bob.collections.arrayEnumerator(null); });

            var array = [1, 2, 3];
            var arrayEnum = bob.collections.arrayEnumerator(array);
            bob.assert.isUndefined(arrayEnum.get_current());
            for (var i = 0; i < array.length; i++) {
                bob.assert.isTrue(arrayEnum.next());
                bob.assert.equals(array[i], arrayEnum.get_current());
            }
            bob.assert.isFalse(arrayEnum.next());

        };

        this.test_stringEnumerator = function () {

            bob.assert.throwsError(function () { bob.collections.stringEnumerator(null); });

            var str = 'asdfg';
            var strEnum = bob.collections.stringEnumerator(str);
            bob.assert.isUndefined(strEnum.get_current());
            for (var i = 0; i < str.length; i++) {
                bob.assert.isTrue(strEnum.next());
                bob.assert.equals(str[i], strEnum.get_current());
            }
            bob.assert.isFalse(strEnum.next());

        };

        this.test_objectEnumerator = function () {

            bob.assert.throwsError(function () { bob.collections.objectEnumerator(null); });

            var obj = { a: 1, b: 2, c: 3 };
            var objEnum = bob.collections.objectEnumerator(obj);

            var objArray = [{ name: 'a', value: 1 }, { name: 'b', value: 2 }, { name: 'c', value: 3}];
            bob.assert.isUndefined(objEnum.get_current());
            for (var i = 0; i < objArray.length; i++) {
                bob.assert.isTrue(objEnum.next());
                bob.assert.equals(objArray[i].name, objEnum.get_current().name);
                bob.assert.equals(objArray[i].value, objEnum.get_current().value);
            }
            bob.assert.isFalse(objEnum.next());
        };

        this.test_objectIndexerEnumerator = function () {

            bob.assert.throwsError(function () { bob.collections.objectIndexerEnumerator(null); }, '1');

            var obj = { a: 1, b: 2, c: 3 };
            var objEnum = bob.collections.objectIndexerEnumerator(obj);

            var objArray = [{ name: 'a', value: 1 }, { name: 'b', value: 2 }, { name: 'c', value: 3}];
            bob.assert.isUndefined(objEnum.get_current(), '2');
            for (var i = 0; i < objArray.length; i++) {
                bob.assert.isTrue(objEnum.next(), '3');
                bob.assert.equals(objArray[i].name, objEnum.get_index(), '4');
                bob.assert.equals(objArray[i].value, objEnum.get_current(), '5');
                bob.assert.equals(objArray[i].name, objEnum.get_index(), '6');
            }
            bob.assert.isFalse(objEnum.next());
        };

        this.test_CollectionCreator = function () {

            bob.assert.throwsError(function () { new bob.collections.CollectionCreator(null, function () { }); }, '1');
            bob.assert.throwsError(function () { new bob.collections.CollectionCreator(function () { }, null); }, '2');

            var _item = 0;
            var _index = 0;
            var fnAddItem = function (index, item) {
                _item = item;
                _index = index;
            };
            var _value = 123;
            var fnGetValue = function () {
                return _value;
            };

            var cc = new bob.collections.CollectionCreator(fnAddItem, fnGetValue);

            var p_item = 1;
            var p_index = 2;
            cc.addItem(p_index, p_item);
            bob.assert.equals(p_index, _index);
            bob.assert.equals(p_item, _item);

            var p_item = 5;
            var p_index = 4;
            cc.addItem(p_index, p_item);
            bob.assert.equals(p_index, _index);
            bob.assert.equals(p_item, _item);

            bob.assert.equals(_value, cc.getValue());
        };

        this.test_arrayCreator = function () {

            var ac = bob.collections.arrayCreator();

            var v = ac.getValue();
            bob.assert.isTrue(bob.utils.isArray(v), '1');
            bob.assert.equals(0, v.length, '2');

            ac.addItem(0, 123);
            var v = ac.getValue();
            bob.assert.isTrue(bob.utils.isArray(v), '3');
            bob.assert.isTrue(bob.collections.extensions.equals.call([123], v), '4');

            ac.addItem(-1, 321);
            var v = ac.getValue();
            bob.assert.isTrue(bob.utils.isArray(v), '5');
            bob.assert.isTrue(bob.collections.extensions.equals.call([123, 321], v), '6');
        };

        this.test_stringCreator = function () {

            var sc = bob.collections.stringCreator();

            var v = sc.getValue();
            bob.assert.isTrue(bob.utils.isString(v), '1');
            bob.assert.equals('', v, '2');

            sc.addItem(0, 'T');
            var v = sc.getValue();
            bob.assert.isTrue(bob.utils.isString(v), '3');
            bob.assert.equals('T', v, '4');

            sc.addItem(0, 'engi');
            var v = sc.getValue();
            bob.assert.isTrue(bob.utils.isString(v), '5');
            bob.assert.equals('Tengi', v, '6');

            sc.addItem(0, 'z');
            var v = sc.getValue();
            bob.assert.isTrue(bob.utils.isString(v), '7');
            bob.assert.equals('Tengiz', v, '8');
        };

        this.test_objectCreator = function () {

            var oc = bob.collections.objectCreator();

            var v = oc.getValue();
            bob.assert.isTrue(bob.utils.isObject(v), '1');
            bob.assert.isTrue(bob.collections.extensions.equals.call({}, v, null), '2');

            oc.addItem('name', 'bob.js');
            bob.assert.isTrue(bob.utils.isObject(v), '3');
            bob.assert.isTrue(bob.collections.extensions.equals.call({ name: 'bob.js' }, v, null), '4');

            oc.addItem('version', 123);
            bob.assert.isTrue(bob.utils.isObject(v), '5');
            bob.assert.isTrue(bob.collections.extensions.equals.call({ name: 'bob.js', version: 123 }, v, null), '6');
        };

        this.test_extend = function () {
            var ec = bob.collections.extend([1, 2, 3, 4]);
            var res = ec.where(function (index, item) { return bob.collections.extensions.indexOf.call([2, 3], true, item) >= 0; }).getValue();
            bob.assert.isTrue(bob.collections.extensions.equals.call([2, 3], res), '1');

            var ec = bob.collections.extend([1, 2, 3, 4]);
            var res = ec.where(function (index, item) { return true; }).sum();
            bob.assert.equals(1 + 2 + 3 + 4, res, '2');
        };
    }

});